@using Humanizer
@using StardewModdingAPI.Web.Framework
@using StardewModdingAPI.Web.ViewModels.JsonValidator
@model JsonValidatorModel

@{
    // get view data
    string curPageUrl = this.Url.PlainAction("Index", "JsonValidator", new { schemaName = Model.SchemaName, id = Model.PasteId }, absoluteUrl: true)!;
    string newUploadUrl = this.Url.PlainAction("Index", "JsonValidator", new { schemaName = Model.SchemaName })!;
    string? schemaDisplayName = null;
    bool isValidSchema = Model.SchemaName != null && Model.SchemaFormats.TryGetValue(Model.SchemaName, out schemaDisplayName) && schemaDisplayName.ToLower() != "none";

    // build title
    ViewData["Title"] = "JSON validator";
    @if (Model.PasteId != null)
    {
        ViewData["ViewTitle"] = ViewData["Title"];
        ViewData["Title"] +=
            " ("
            + string.Join(", ", new[] { isValidSchema ? schemaDisplayName : null, Model.PasteId }.Where(p => p != null))
            + ")";
    }
}

@section Head {
    @if (Model.PasteId != null)
    {
        <meta name="robots" content="noindex" />
    }

    <!-- jQuery -->
    <script src="@Url.ContentWithCacheBust("~/Content/lib/jquery/dist/jquery.min.js")"></script>

    <!-- Prism -->
    <link rel="stylesheet" href="@Url.ContentWithCacheBust("~/Content/lib/prism-themes/themes/prism-vs.min.css")" />
    <script src="@Url.ContentWithCacheBust("~/Content/lib/prismjs/prism.min.js")"></script>
    <script src="@Url.ContentWithCacheBust("~/Content/lib/prismjs/components/prism-json.min.js")"></script>

    <!-- Prism line numbers -->
    <link rel="stylesheet" href="@Url.ContentWithCacheBust("~/Content/lib/prismjs/plugins/line-numbers/prism-line-numbers.min.css")" />
    <script src="@Url.ContentWithCacheBust("~/Content/lib/prismjs/plugins/line-numbers/prism-line-numbers.min.js")"></script>

    <!-- Prism line highlight -->
    <link rel="stylesheet" href="@Url.ContentWithCacheBust("~/Content/lib/prismjs/plugins/line-highlight/prism-line-highlight.min.css")" />
    <script src="@Url.ContentWithCacheBust("~/Content/lib/prismjs/plugins/line-highlight/prism-line-highlight.min.js")"></script>

    <!-- Prism toolbar -->
    <link rel="stylesheet" href="@Url.ContentWithCacheBust("~/Content/lib/prismjs/plugins/toolbar/prism-toolbar.min.css")" />
    <script src="@Url.ContentWithCacheBust("~/Content/lib/prismjs/plugins/toolbar/prism-toolbar.min.js")"></script>

    <!-- Prism copy to clipboard -->
    <script src="@Url.ContentWithCacheBust("~/Content/lib/prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js")"></script>

    <!-- Prism match braces -->
    <link rel="stylesheet" href="@Url.ContentWithCacheBust("~/Content/lib/prismjs/plugins/match-braces/prism-match-braces.min.css")" />
    <script src="@Url.ContentWithCacheBust("~/Content/lib/prismjs/plugins/match-braces/prism-match-braces.min.js")"></script>

    <!-- page CSS/JS -->
    <link rel="stylesheet" href="@Url.ContentWithCacheBust("~/Content/css/file-upload.css")" />
    <link rel="stylesheet" href="@Url.ContentWithCacheBust("~/Content/css/json-validator.css")" />
    <script src="@Url.ContentWithCacheBust("~/Content/js/file-upload.js")"></script>
    <script src="@Url.ContentWithCacheBust("~/Content/js/json-validator.js")"></script>

    <!-- init -->
    <script>
        $(function() {
            smapi.jsonValidator(@this.ForJson(this.Url.PlainAction("Index", "JsonValidator", new { schemaName = "$schemaName", id = "$id" })), @this.ForJson(Model.PasteId));
        });
    </script>
}

@* upload result banner *@
@if (Model.UploadError != null)
{
    <div class="banner error">
        <strong>Oops, the server ran into trouble saving that file.</strong><br />
        <small>Error details: @Model.UploadError</small>
    </div>
}
else if (Model.ParseError != null)
{
    <div class="banner error">
        <strong>Oops, couldn't parse that JSON.</strong><br />
        Share this link to let someone see this page: <code>@curPageUrl</code><br />
        (Or <a href="@newUploadUrl">validate a new file</a>.)<br />
        <br />
        <small v-pre>Error details: @Model.ParseError</small>
    </div>
}
else if (Model is { IsEditView: false, PasteId: not null })
{
    <div class="banner success">
        <strong>Share this link to let someone else see this page:</strong> <code>@curPageUrl</code><br />
        (Or <a href="@newUploadUrl">validate a new file</a>.)
    </div>
}

@* save warnings *@
@if (Model.UploadWarning != null || Model.NewExpiry.HasValue)
{
    <div class="save-metadata" v-pre>
        @if (Model.NewExpiry != null)
        {
            string? oldExpiryText = Model.OldExpiry.HasValue
                ? (DateTime.UtcNow - Model.OldExpiry.Value).Humanize()
                : null;
            string? newExpiryText = Model.NewExpiry.HasValue
                ? (DateTime.UtcNow - Model.NewExpiry.Value).Humanize()
                : null;

            <text>This JSON file will expire in </text>
            @if (oldExpiryText != null && oldExpiryText != newExpiryText)
            {
                <text><s>@(oldExpiryText)</s> </text>
            }
            <text>@(newExpiryText) (<a href="@(this.Url.PlainAction("Index", "JsonValidator", new { schemaName = this.Model.SchemaName, id = this.Model.PasteId, operation = "renew" }))">renew</a>).</text>
        }
        <!--@Model.UploadWarning-->
    </div>
}

@* upload new file *@
@if (Model.IsEditView)
{
    <h2>Upload a JSON file</h2>
    <form action="@this.Url.PlainAction("PostAsync", "JsonValidator")" method="post">
        <input id="inputFile" type="file" />
        <ol>
            <li>
                Choose the JSON format:<br />
                <select id="format" name="SchemaName">
                    @foreach (var pair in Model.SchemaFormats)
                    {
                        <option value="@pair.Key" selected="@(Model.SchemaName == pair.Key)">@pair.Value</option>
                    }
                </select>
            </li>
            <li>
                Drag the file onto this textbox <small>(or <a href="#" id="choose-file-link">choose a file</a>)</small>:<br />
                <textarea id="input" name="Content" placeholder="paste file here">@Model.Content</textarea>
            </li>
            <li>
                Click this button:<br />
                <input type="submit" id="submit" value="save & validate file" />
            </li>
        </ol>
    </form>
}

@* validation results *@
@if (!Model.IsEditView)
{
    <div id="output">
        @if (Model.UploadError == null)
        {
            <h2>Validation</h2>
            <p>
                @(Model.Errors.Any() ? "Oops, found some issues with your JSON." : "No errors found!")
                @if (!isValidSchema)
                {
                    <text>(You have no schema selected, so only the basic JSON syntax was checked.)</text>
                }
                else if (Model.FormatUrl != null)
                {
                    <text>See <a href="@Model.FormatUrl">format documentation</a> for more info.</text>
                }
            </p>

            @if (Model.Errors.Any())
            {
                <table id="metadata" class="table">
                    <tr>
                        <th>Line</th>
                        <th>Field</th>
                        <th>Error</th>
                    </tr>

                    @foreach (JsonValidatorErrorModel error in Model.Errors)
                    {
                        <tr data-schema-error="@error.SchemaErrorType">
                            <td><a href="#code.@(error.Line)">@error.Line</a></td>
                            <td>@error.Path</td>
                            <td>@error.Message</td>
                        </tr>
                    }
                </table>
            }
        }

        <h2>Content</h2>
        <div>
            You can change JSON format (<select id="format" name="format">
                @foreach (var pair in Model.SchemaFormats)
                {
                    <option value="@pair.Key" selected="@(Model.SchemaName == pair.Key)">@pair.Value</option>
                }
            </select>) or <a href="@(this.Url.PlainAction("Index", "JsonValidator", new { id = this.Model.PasteId, schemaName = this.Model.SchemaName, operation = "edit" }))">edit this file</a>.
        </div>
        <pre id="code" class="language-json line-numbers linkable-line-numbers match-braces"><code>@Model.Content</code></pre>

        @if (isValidSchema)
        {
            <p class="footer-tip">(Tip: you can <a href="https://github.com/Pathoschild/SMAPI/blob/develop/docs/technical/web.md#using-a-schema-file-directly">validate directly in your text editor</a> if it supports JSON Schema.)</p>
        }
    </div>
}
